package cn.zwx.learn.basic.groovy.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.zwx.learn.basic.groovy.GroovyService;
import cn.zwx.learn.basic.groovy.handler.GroovyHandler;
import cn.zwx.learn.basic.groovy.register.CommonGroovyRegister;
import cn.zwx.learn.basic.groovy.register.GroovyRegister;
import com.sun.org.apache.bcel.internal.generic.IFLE;
import groovy.lang.GroovyClassLoader;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import java.io.*;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @description:
 * @projectName:java-basic
 * @see:groovy.impl
 * @author:zhangwenxue
 * @createTime:2021/4/13 18:28
 * @version:1.0
 */
@Service
public class GroovyServiceImpl implements GroovyService {

    private static final Logger logger = LoggerFactory.getLogger(GroovyServiceImpl.class);
    /**
     * @description 用于groovy缓存
     **/
    public static Map groovyCache = new ConcurrentHashMap();

    /**
     * @description 加载groovy classsLoader
     **/
    private GroovyClassLoader groovyClassLoader = new GroovyClassLoader();

    private GroovyRegister groovyRegister = GroovyRegister.getInstance();

    private CommonGroovyRegister commonGroovyRegister = CommonGroovyRegister.getInstance();


    /**
     * @description 以文件形式加载groovy对象
     * @return java.util.Map<java.lang.String,java.lang.String>
     * @author zhangwenxue
     * @createTime 2021/4/13 18:44
     **/
    private Map<String, String> mapFileByDir(File file) throws IOException {
        Map<String, String> result = CollectionUtil.newHashMap();
        File[] fs = file.listFiles();
        for (File f : fs) {
            if (f.isDirectory()) {
                Map<String, String> sub = mapFileByDir(f);
                result.putAll(sub);
            } else {
                result.put(f.getName().substring(0, f.getName().lastIndexOf(".")), FileUtils.readFileToString(f, Charset.defaultCharset()));
            }
        }
        return result;
    }


    @Override
    public void loadClsGroovy() throws Exception {
        File clsDir = ResourceUtils.getFile("classpath:action");
        Map<String, String> commonMap = mapFileByDir(clsDir);
        if (CollectionUtil.isEmpty(commonMap)){
            logger.info("未加载到groovy脚本!!!");
            return;
        }
        commonMap.entrySet().forEach(entry -> {
            try {
                String groovyContent = entry.getValue();
                if (Objects.nonNull(groovyContent)){
                    String groovyMd5 = DigestUtils.md5Hex(groovyContent);
                    if (null == groovyCache.get(entry.getKey()) || !groovyCache.get(entry.getKey()).equals(groovyMd5)) {

                        logger.info(entry.getKey() + "脚本发生变化开始刷新");
                        Class<?> groovyClass = groovyClassLoader.parseClass(groovyContent, entry.getKey());
                        groovyRegister.put(entry.getKey(), (GroovyHandler) groovyClass.newInstance());

                        groovyCache.put(entry.getKey(), groovyMd5);
                        logger.info(entry.getKey() + "脚本刷新完成");

                    }
                }else {
                    logger.info("未检测到脚本内容,脚本Key:{}",entry.getKey());
                }
            } catch (Exception e) {
                logger.error("grovvy 加载class失败，请查看groovy代码：" + entry.getKey());
            }
        });
    }



    @Override
    public void loadClsGroovy(String key) throws Exception {

        logger.info("加載路徑path:{}","action\\test\\Cls_rule_2.groovy");
//        String groovyContent = FileUtils.readFileToString(new File("D:\\workspace\\java-basic\\target\\classes\\action\\test\\Cls_rule_2.groovy"), Charset.defaultCharset());

        String groovyContent = "";
        FileInputStream fileInputStream = new FileInputStream(new File("D:\\workspace\\java-basic\\src\\main\\resources\\action\\test\\Cls_rule_2.groovy"));
        BufferedInputStream bufferedInputStream = new  BufferedInputStream(fileInputStream);
        byte[] buffer = new byte[1024];
        int bytesRead ;
        while ((bytesRead = bufferedInputStream.read(buffer)) != -1) {
            //将读取的字节转为字符串对象
            groovyContent += new String(buffer, 0, bytesRead);
        }

        fileInputStream.close();
        bufferedInputStream.close();
        
        key = key.substring(key.lastIndexOf(".")+ 1);
        if (Objects.nonNull(groovyContent)){
            String groovyMd5 = DigestUtils.md5Hex(groovyContent);
            logger.info(key + "脚本发生变化开始刷新");
            Class<?> groovyClass = groovyClassLoader.parseClass(groovyContent, key);
            groovyRegister.put(key, (GroovyHandler) groovyClass.newInstance());
            groovyCache.put(key, groovyMd5);
            logger.info(key + "脚本刷新完成");
        }else {
            logger.info("未检测到脚本内容,脚本Key:{}",key);
        }
    }

    

}
